home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 13886 < prev    next >
Encoding:
Text File  |  1996-08-05  |  10.5 KB  |  201 lines

  1. Newsgroups: comp.lang.ada,comp.lang.c++
  2. Path: netcom.com!wnewman
  3. From: wnewman@netcom.com (Bill Newman)
  4. Subject: some questions re. Ada/GNAT from a C++/GCC user
  5. Message-ID: <wnewmanDoxrCp.DKv@netcom.com>
  6. Followup-To: comp.lang.ada,comp.lang.c++
  7. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  8. X-Newsreader: TIN [version 1.2 PL1]
  9. Date: Wed, 27 Mar 1996 17:02:49 GMT
  10. Sender: wnewman@netcom6.netcom.com
  11.  
  12. I have been skimming _Ada as a Second Language_ (second edition) and I
  13. have looked at the GNAT documentation.  I am impressed: Ada and GNAT
  14. look like they should do a pretty good job of meeting their design
  15. criteria.  However, before I start planning my next project in Ada :-)
  16. there are a few things I'd like to know..  (I hope against hope that
  17. the tone of the answers will resemble the cross-language comparisons
  18. in _Ada as a Second Language_ more closely than it resembles the
  19. recent C++/Ada flamewar.)
  20.  
  21. The Ada Programming FAQ pooh-poohs STL, but I like it.  (Yes, I know I
  22. could write my own versions of what I need, but a bunch of Ada
  23. programmers shouldn't need to be told that that's not the ideal
  24. solution.)  This FAQ also says the Booch components library is coming
  25. -- when?
  26.  
  27. Does GNAT completely implement generics as defined in the standard?
  28. (I ask because I have heard that no compiler, G++ otherwise, has yet
  29. implemented C++ templates completely, and the G++ implementation
  30. caused me lots of hassles before 2.7.x, and still causes some hassles
  31. now.)
  32.  
  33. I *assume* that GNAT supports exceptions completely since they're an integral
  34. part of the language and I didn't see any disclaimers, but since AFAIK G++
  35. doesn't do them very well, I'd like to double-check: how well does
  36. GNAT do exceptions?
  37.  
  38. I didn't notice anything about garbage collection in the GNAT docs, so
  39. I assume it doesn't support it.  Will GNAT support GC in the
  40. foreseeable future?
  41.  
  42. How well does GDB work with GNAT output?  Is it possible to get GDB to
  43. interactively call arbitrary procedures/functions from GNAT-generated
  44. code?  I have been very frustrated by the way that I can't get GDB to
  45. call operator<<(ostream&, const Some_Class&) interactively, which
  46. makes it very painful to inspect the state of a program produced by
  47. G++.  (I do *not* appreciate having to inspect my data raw field by
  48. raw field for every object in a complicated graph.)  Would I have the
  49. same problem when inspecting the state of programs produced by GNAT?
  50.  
  51. Is there any way in Ada to iterate abstractly over the contents of a 
  52. container, i.e. without writing each loop in a way which depends
  53. strongly on the implementation of the container?  I know I 
  54. could define a container class Foo_Basket_Type which would 
  55. let me do something like
  56.     for I = 1 .. Size(Foo_Basket) loop -- class implemented as array
  57.        Sum := Sum + Bletchery(Element(Foo_Basket, I));
  58.     end loop;
  59. or 
  60.     I : Foo_Basket_Iterator_Type := Head(Foo_Basket);
  61.     ..
  62.     while not Is_Done(I) loop -- class implemented as list
  63.        Sum := Sum + Bletchery(dereference I);
  64.        I := Next(I);
  65.     end loop;
  66. but what I'd really like to is something like 
  67.     for each I in Foo_Basket loop -- don't much care how class is implemented
  68.        Sum := Sum + Bletchery(dereference I);
  69.     end loop;
  70. I understand that in languages like Sather, I could do this without
  71. macros.  In G++ I can come pretty close to this with CPP macros:
  72.     FOR_EACH(i, foo_basket)
  73.       sum += bletchery(*i);
  74. In standard C++ (without the G++ `typeof' operator) I'd write something like
  75.     FOR_EACH(i, Foo_Basket::Iterator, foo_basket)
  76.       sum += bletchery(*i);
  77. I use this idiom a lot -- about once per 40 lines of code in my
  78. current project.  I much prefer it to the alternative of making my
  79. code depend on the implementation of the container.  Is there any way of
  80. doing something like this in Ada?  (I imagine there is, since the
  81. alternatives look unnecessarily difficult to maintain.)
  82.     
  83. Due in part to my problems with GDB mentioned above, my C++ programs
  84. tend to contain a lot of calls to macros MUTTER1, MUTTER2,
  85. etc. defined either as no-op (for low levels of verbosity) or as
  86.    #define MUTTER1(x) do { cerr << mutter_prefix << x << '\n'; } while (false)
  87. so that I can write things like 
  88.    MUTTER1("done with sampling, w = " << w << ", table = " << table);
  89. concisely.  It's my impression that Ada's I/O facilities make it hard
  90. to do trivial things like this concisely.  Is this wrong?  I don't really
  91. want to have to write 
  92.    if (Global_Verbosity >= 1) then
  93.      Write_Mutter_Indent(Global_Mutter);
  94.      Write(Global_Mutter, "done with sampling, W = ");
  95.      Write(Global_Mutter, W);
  96.      Write(Global_Mutter, ", table = ");
  97.      Write(Global_Mutter, Table);
  98.      Write_Line(Global_Error); -- silly typo encouraged by excess verbosity
  99.    end if;
  100. for a simple statement like the one above.
  101.  
  102. When I make two different instantiations of a generic package with the
  103. same arguments, I understand the compiler treats them formally as two
  104. different packages, which is OK with me.  However, I'd appreciate
  105. knowing the compiler wouldn't actually output two redundant copies of
  106. the corresponding (identical?) machine code, but instead share the
  107. code.  I saw somewhere that the compiler is given considerable freedom
  108. to share one instantiation between several arguments if it thinks it's
  109. appropriate, which is also OK with me.  However, I haven't seen any
  110. guarantee that the compiler won't output redundant copies for
  111. instantiations with identical arguments.  Is there such a guarantee?
  112.  
  113. Can someone give me an idea what kind of compilation speed I could
  114. expect from GNAT on a 486DX2/66 with 20 Mb of RAM, for projects of
  115. 1,000-50,000 lines?  (I'm interested both in the time required for
  116. complete recompilation and in the time required for recompilation
  117. after a trivial local change.)
  118.  
  119. My examples of `for each' and `mutter' above share a common feature:
  120. I'd like to abstract away a common pattern so that I only need to type
  121. each argument once, and I haven't figured out how to do it in Ada.  I
  122. don't object to the rest of the verbosity I have seen in Ada: I can
  123. see that it might make programs more readable, and since it's checked
  124. by the compiler it shouldn't make programs significantly harder to
  125. maintain.  However, the kind of verbosity required to hand-code
  126. patterns like `for each' and `mutter' does not seem to make code more
  127. readable, and since it is not checked by the compiler I'm afraid it
  128. might cause maintenance problems by making it possible to add bugs by
  129. changing some but not all occurrences of the redundant terms.  Are
  130. there ways (e.g.  in the cases described above, or other cases that I
  131. haven't thought of yet) in which Ada will force me to do this kind of
  132. thing where C++ wouldn't?  If so, is this a bad thing (as I suspect),
  133. or is it a positive feature in some sense that I haven't figured out,
  134. or is it just the price we pay for the benefit of being guaranteed
  135. that no one has abused macros in the program?
  136.  
  137. I also have a few idle questions about the design and application of
  138. Ada 95, more-or-less unrelated to the question of whether I'll decide
  139. to use it:
  140.  
  141. Why doesn't Ada 95 allow declarations to be interspersed with ordinary
  142. statements as C++ does?  (Or does it?  _Ada as a Second Language_ is a
  143. big book!)  It seems to me that the C++ approach is a small but
  144. definite win.  Does it interact very badly somehow with all those
  145. guarantees on elaboration order?
  146.  
  147. Someone remarked -- in this newsgroup recently IIRC -- that macros
  148. were explicitly disallowed in the design goals for Ada (Ada 83?),
  149. since they make programs hard to understand.  I don't remember the
  150. exact wording, but as I remember the key reason was that you would
  151. never know what was a macro and what wasn't without reading the entire
  152. program hunting for macro definitions.  (I searched for `macro' in the
  153. Rationale without success, so I'm just going on speculation and dim
  154. memory here.)  It seems to me that that is a funny objection: most
  155. macro processors these days don't require a characteristic pattern to
  156. introduce macro expansions, but as far as I can tell there's no reason
  157. that you couldn't restrict macro expansion to e.g. patterns preceded
  158. by the keyword `macro'.  Granted, C's macro facilities are fairly
  159. disgusting and inconsistent with the design goals of Ada, but it seems
  160. to me a macro facility (or `generic syntax' facility?) more consistent
  161. with Ada could be useful -- perhaps something closer to Scheme's
  162. `hygienic macros' than to C's macro preprocessor.  Some restrictions
  163. (e.g. only allowing macros to expand into expressions, sequences of
  164. statements, or sequences of declarations, and not into arbitrary textual
  165. strings) and perhaps importing from Lisp the idea that macros are
  166. transformations on patterns of language tokens and expressions, rather
  167. than transformations on patterns of characters) could do a pretty
  168. decent job of discouraging people from writing truly screwy macros
  169. without forbidding useful macros like `For_Each' or (to generalize
  170. `MUTTER') `Write_Sequence' (sending a bunch of items to the same
  171. stream, and using the language's overloading facility to sort out
  172. which version of the Write procedure to call for each).  Would this
  173. have been a good idea, except perhaps that the language is too
  174. complicated already, or would this be a bad idea for some more
  175. fundamental reason?
  176.  
  177. Finally, I found it intriguing when someone (somewhere in the endless
  178. C++ vs. Ada thread) described a program which used exceptions to
  179. convert runtime errors to `graceful degradation' so successfully that
  180. the program (for fire control?!) continued operating more-or-less
  181. correctly despite numerous bugs.  It seems to me that for the kinds of
  182. programs that I typically work on, that this would require more than
  183. exceptions (perhaps divine intervention?)  but I can imagine that it
  184. would be possible for a program which was conceptually like a bunch of
  185. closed-loop feedback systems, without a lot of state.  Therefore, it's
  186. my guess that the program in question was such a program.  Is that a
  187. sensible guess?  If not, i.e. if this kind of performance would be
  188. possible in a program with lots of state, can someone give me a
  189. pointer to the theory of this kind of thing?  (And are there any
  190. examples of such fault-tolerant programs available on the net?)
  191. (Examples of programs with lots of state include computer operating
  192. systems like UNIX (or Emacs:-), or perhaps an air-traffic control
  193. system which needs to base its output on data up to twenty hours old
  194. regarding flight departure times, radar and weather reports, etc.  An
  195. example of a system without much state would be a translation of a
  196. system of analog radar-guided AA gun controllers directly into
  197. software.)
  198.  
  199.   Bill Newman
  200.   wnewman@netcom
  201.